home *** CD-ROM | disk | FTP | other *** search
- // Copyright (C) 1997-2002 Alias|Wavefront,
- // a division of Silicon Graphics Limited.
- //
- // The information in this file is provided for the exclusive use of the
- // licensees of Alias|Wavefront. Such users have the right to use, modify,
- // and incorporate this code into other products for purposes authorized
- // by the Alias|Wavefront license agreement, without fee.
- //
- // ALIAS|WAVEFRONT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- // INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- // EVENT SHALL ALIAS|WAVEFRONT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- // PERFORMANCE OF THIS SOFTWARE.
- //
- // smoothParamSurface - reparameterize a surface to get smoother parameter
- // distribution in both directions
- //
- // Usage:
- // smoothParamSurface(int <history>, int <nsamples>);
- //
- // where: <history> is a toggle turning history on or off
- // <nsamples> is the number of output patches per input patch
- // in the U direction.
- //
- // How it works:
- // 1. Extracts isoparms in V direction, rebuilds as uniform
- // 2. Lofts these splines in U using chord length option
- //
- // Usage hints:
- // - Using a larger number of samples increases accuracy, but can get
- // slow. Try with 1 first, then increase as needed.
- // - history on means the original surface can be tweaked and the changes
- // will be seen on the reparameterized surface, but the cost is the storage
- // of a large number of intermediate curves used to generate the reparameterized
- // surface.
- //
- // Author: MPW
- //
- //
- proc int getNurbsSurfaceKnots(string $srfName, float $uKnots[], float $vKnots[] )
- //
- // Description :
- // Get surface knots in U and V
- {
-
- // create info Node.
- string $infoNode ;
- if( catch( $infoNode = `createNode surfaceInfo` ) ) {
- return 1; // failed
- }
-
- // connect surface on to the info node.
- string $outAttr = $srfName + ".local" ;
- string $inAttr = $infoNode + ".is" ;
- connectAttr $outAttr $inAttr ;
-
- // read the knots.
- $uKnots = `getAttr ($infoNode + ".knotsU")`;
- $vKnots = `getAttr ($infoNode + ".knotsV")`;
-
- // delete surface info node.
- delete $infoNode ;
-
- // worked
- return 0;
- }
-
- proc int getNurbsSurfaceSmoothParam(
- string $srf, int $ch, int $samplesPerSpan)
- //
- // Description :
- // Compute reparam surface by computing points
- // regularly spaced in U and V on the surface, fitting curves
- // and then lofting a surface through the curves.
- //
- {
- int $i; // loop counter
-
- // number of spans
- int $nspansU = eval("getAttr " + $srf + ".spansU");
-
- // degree
- int $degreeU = eval("getAttr " + $srf + ".degreeU");
-
- // knots
- float $uKnots[];
- float $vKnots[];
- if(getNurbsSurfaceKnots($srf, $uKnots, $vKnots)) {
- return 1; // failed
- }
-
- // first and last knot values to use
- int $firstU = $degreeU - 1;
- int $lastU = $nspansU + $firstU;
-
- // loop over knot values
- int $uIndex, $vIndex;
- int $uSample, $vSample;
- int $uSampleMax, $vSampleMax;
- float $u;
-
- string $allCurves;
-
- // check if periodic in U. If so, dont need to evaluate last U
- // isoparm on surface since it is coincident with the first
- int $formInU = eval("getAttr " + $srf + ".formU");
-
- // loop over U spans
- for($uIndex = $firstU; $uIndex < $lastU; $uIndex++) {
-
- // maximum number of samples for this span
- $uSampleMax = ($formInU == 2 || $uIndex < $lastU-1) ? $samplesPerSpan - 1 : $samplesPerSpan;
-
- // parameter interval for this span
- float $uInterval = $uKnots[$uIndex+1] - $uKnots[$uIndex];
-
- // loop over U samples
- for($uSample = 0; $uSample <= $uSampleMax; $uSample++) {
-
- // get value of U
- $u = $uKnots[$uIndex] + $uSample*$uInterval/float($samplesPerSpan);
- // make sure rouding errors dont take it off the end
- if($uIndex == ($formInU == 2 || $lastU-1) && $uSample == $uSampleMax) {
- $u = $uKnots[$lastU];
- }
-
- // extract this isoparm
- string $dup[] = eval("duplicateCurve -ch " + $ch + " -rn 0 -local 0 " + $srf + ".u[" + $u + "]");
- int $nspans = eval("getAttr " + $dup[0] + ".spans");
- // rebuild isoparm with uniform knots - replace original extracted isoparm
- string $reb[] = eval("rebuildCurve -ch " + $ch + " -rpo 1 -rt 0 -kr 1 -kcp 0 -kep 1 -kt 0 -s " + $nspans + " -d 3 -tol 0.05 " + $dup[0]);
-
- $allCurves += " " + $reb[0];
- }
- }
- //print ("All curves are: " + $allCurves + "\n");
-
- // now loft the curves using reparam option
- string $loftCmd = "loft -ch " + $ch + " -d 3 -u 0";
- if($formInU == 2) $loftCmd += " -c on ";
- $loftCmd += $allCurves;
- //print("Loft command is " + $loftCmd + "\n");
-
- // close flag - check basic surface first...
- string $outsrf[] = eval($loftCmd);
- print ("Created reparam surface " + $outsrf[0] + "\n");
-
- // delete all input curves if no history requested
- if(0 == $ch) {
- eval("delete " + $allCurves);
- }
-
- // return the surface name??
- return 0;
- }
-
-
- global proc smoothParamSurface(int $ch, int $samplesPerSpan)
- {
-
- if($ch>=1) {
- print "Setting construction history on\n";
- $ch = 1;
- }
-
- if($ch<=0) {
- print "Setting construction history off\n";
- $ch = 0;
- }
-
- // always need at least one sample per span
- if($samplesPerSpan < 1) $samplesPerSpan = 1;
-
- // Run filter to select only the NURBS surfaces
- global int $gSelectNurbsSurfacesBit ;
- string $srfList[] = `filterExpand -ex true
- -sm $gSelectNurbsSurfacesBit`;
- int $len = size($srfList) ;
- if( $len == 0 ) {
- print "No NURBS surfaces selected\n" ;
- return;
- }
-
- // Work on all surfaces
- for($srfNum = 0; $srfNum < $len; $srfNum++) {
- string $srf = $srfList[$srfNum] ;
-
- // do the smoothParam
- if(getNurbsSurfaceSmoothParam($srf, $ch, $samplesPerSpan)) {
- print ("Failed to reparameterize surface " + $srf + "\n");
- break;
- }
- }
-
- }
-